package com.songlanyun.modules.userbank.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.songlanyun.common.drive.Validator;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.common.validator.group.AddGroup;
import com.songlanyun.common.validator.group.UpdateGroup;
import com.songlanyun.modules.account.entity.AccountEntity;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.cnarea.service.CnAreaService;
import com.songlanyun.modules.exception.MemberException;
import com.songlanyun.modules.userbank.dao.UserBankDao;
import com.songlanyun.modules.userbank.entity.UserBank;
import com.songlanyun.modules.userbank.model.dto.UserBankDTO;
import com.songlanyun.modules.userbank.service.UserBankService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.security.UnresolvedPermission;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;

import com.songlanyun.modules.userbank.dao.UserBankDao;
import com.songlanyun.modules.userbank.entity.UserBank;
import com.songlanyun.modules.userbank.service.UserBankService;
import org.springframework.transaction.annotation.Transactional;


@Service("saleUserbankService")
public class UserBankServiceImpl extends ServiceImpl<UserBankDao, UserBank> implements UserBankService {

    @Autowired
    private AccountService service;

    @Autowired
    private CnAreaService cnAreaService;

    @Override
    public UserBank create(UserBank entity) {
//        ValidatorUtils.validateEntity(entity, AddGroup.class);
        this.baseMapper.insert(entity);
        return entity;
    }


    @Override
    public UserBank modify(UserBank entity) {
//        ValidatorUtils.validateEntity(entity, UpdateGroup.class);
        this.baseMapper.updateById(entity);
        return entity;
    }

    @Override
    public void remove(Long id) {
        this.removeById(id);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<UserBank> page = this.page(
                new Query<UserBank>().getPage(params),
                new QueryWrapper<UserBank>()
        );

        return new PageUtils(page);
    }

    /**
     * 会员创建收货地址
     *
     * @param userId
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public UserBank add(Long userId, UserBankDTO dto) {
        AccountEntity user = service.getUserById(userId, true);
        Integer count = this.baseMapper.selectCount(
                new LambdaQueryWrapper<UserBank>()
                        .eq(UserBank::getUserId, userId)
        );

        if (count >= 10) {
            throw new RRException(MemberException.USER_BANK_CARD_NOT_EXISTS);
        }

        UserBank def = this.getDefaultByUserId(userId);
        if (def == null) {
            //如果没有默认的收货地址，当前就是默认
            dto.setIsDefault(true);
        } else {
            //如果有默认收货地址，如果当前的这个要设置成为默认的,那么之前的那个默认的要设置非默认
            if (dto.getIsDefault()) {
                def.setIsDefault(false);
                this.modify(def);
            }
        }
        UserBank bank = new UserBank();
        BeanUtils.copyProperties(dto, bank);

        //设置行政编码
        setCode(bank);

        bank.setUserId(user.getId());
        bank = this.create(bank);
        return bank;
    }

    /**
     * 会员修改收货地址
     *
     * @param userId
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public UserBank update(Long userId, UserBankDTO dto) {
        AccountEntity user = service.getUserById(userId, true);
        UserBank load = this.getByUserIdAndId(user.getId(), dto.getId());
        if (load == null) {
            throw new RRException(MemberException.USER_BANK_CARD_NOT_EXISTS);
        }

        UserBank def = this.getDefaultByUserId(userId);
        //如果当前的要设置默认的
        if (dto.getIsDefault()) {
            //自己的默认的与当前的不是一个对象，则之前默认的变为非默认
            if (def != null && !def.equals(load)) {
                def.setIsDefault(false);
                this.modify(def);
            }

        } else {
            //如果当前的要设置成非默认的
            //如果默认的地址是当前要修改的地址，设置成非默认无效
            if (def != null && def.equals(load)) {
                dto.setIsDefault(true);
            }
        }
        BeanUtils.copyProperties(dto, load);
        //设置行政编码
        setCode(load);
        return this.modify(load);
    }

    /**
     * 会员删除收货地址
     *
     * @param userId
     * @param id
     * @return
     */
    @Override
    public void remove(Long userId, Long id) {
        UserBank load = this.getByUserIdAndId(userId, id);
        if (load == null) {
            throw new RRException(MemberException.USER_BANK_CARD_NOT_EXISTS);
        }
        if (load.getIsDefault()) {
            //不要删除默认收货地址
            throw new RRException(MemberException.USER_BANK_CARD_NOT_EXISTS);
        }
        this.remove(load.getId());
    }

    /**
     * 会员获取收货地址
     *
     * @param userId
     * @param id
     * @return
     */
    @Override
    public UserBank getByUserIdAndId(Long userId, Long id) {
        UserBank obj = this.getOne(new LambdaQueryWrapper<UserBank>()
                .eq(UserBank::getId, id)
                .eq(UserBank::getUserId, userId)
                .last("limit 1")
        );
        return obj;
    }

    /**
     * 会员获取默认的收货地址
     *
     * @param userId
     * @return
     */
    @Override
    public UserBank getDefaultByUserId(Long userId) {
        UserBank obj = this.getOne(new LambdaQueryWrapper<UserBank>()
                .eq(UserBank::getIsDefault, true)
                .eq(UserBank::getUserId, userId)
                .last("limit 1")
        );
        return obj;
    }

    /**
     * 设置默认收货地址
     *
     * @param userId
     * @param id
     * @return
     */
    @Override
    public UserBank setDefault(Long userId, Long id) {
        UserBank def = this.getDefaultByUserId(userId);
        UserBank load = this.getByUserIdAndId(userId, id);
        if (load == null) {
            throw new RRException(MemberException.USER_BANK_CARD_NOT_EXISTS);
        }
        load.setIsDefault(true);
        if (def != null && !def.equals(load)) {
            def.setIsDefault(false);
            this.modify(def);
        }

        return this.modify(load);
    }

    /**
     * 会员的收货地址列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<UserBank> mybankList(Long userId) {
        return this.list(
                new LambdaQueryWrapper<UserBank>()
                        .eq(UserBank::getUserId, userId)
                        .orderByDesc(UserBank::getIsDefault)
        );
    }


    /**
     * 设置行政编码
     *
     * @param bank
     */
    private void setCode(UserBank bank) {
        //设置行政编码
        //省
        if (StringUtils.isBlank(bank.getProvinceCode())) {
            bank.setProvinceCode(cnAreaService.getCodeByName(bank.getProvinceName(), null));
        }
        //市
        if (StringUtils.isBlank(bank.getCityCode())) {
            bank.setCityCode(cnAreaService.getCodeByName(bank.getCityName(), bank.getProvinceCode()));
        }
        //区
        if (StringUtils.isBlank(bank.getAreaCode())) {
            bank.setAreaCode(cnAreaService.getCodeByName(bank.getAreaName(), bank.getCityCode()));
        }

    }
}
